//
// Created by sgyt on 2020/4/3.
// 条件变量
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <signal.h>
//定义一把互斥锁
pthread_mutex_t lock;
//条件比那里
pthread_cond_t cond;
//链表结构
typedef struct node{
    int data;
    struct node *next;
}NODE;
NODE *head = NULL;

//消费者线程
void *pthread_customer(void *arg);
//生产者线程
void *pthread_produce(void *arg);

int main(int argc,char *argv[])
{
    int res;
    pthread_t pthread1,pthread2;
    void *resval;
    //初始化锁
    pthread_mutex_init(&lock,NULL);
    pthread_cond_init(&cond,NULL);
    printf("pthread is start\n");
    //创建生产者线程
    res = pthread_create(&pthread1,NULL,pthread_produce,"1");
    if(res != 0){
        perror("pthread_create is error\n");
        exit(EXIT_FAILURE);
    }
    printf("pthread1 is create\n");
    //创建消费者线程
    res = pthread_create(&pthread2,NULL,pthread_customer,"2");
    if(res != 0){
        perror("pthread_create is error\n");
        exit(EXIT_FAILURE);
    }
    printf("pthread2 is create\n");
    //等待线程
    res = pthread_join(pthread1,&resval);
    if(res != 0)
    {
        perror("pthread_join is error\n");
        exit(EXIT_FAILURE);
    }
    printf("pthread1 is join\n");

    res = pthread_join(pthread2,&resval);
    if(res != 0)
    {
        perror("pthread_join is error\n");
        exit(EXIT_FAILURE);
    }
    printf("pthread2 is join\n");

    //释放锁
    pthread_mutex_destroy(&lock);
    //释放锁
    pthread_cond_destroy(&lock);
    //释放条件锁
    return 0;
}

void *pthread_customer(void *arg)
{
    printf("customer is star\n");
    char *name = (char *)arg;
    printf("customer name is [%s]\n",name);
    NODE *node = NULL;

    while(1)
    {
        //上锁
        pthread_mutex_lock(&lock);
        //如果头是空的，那等待
        if(head == NULL)
        {
            pthread_cond_wait(&cond,&lock);
        }

        //消费
        printf("customer:[%d]\n",head->data);
        node = head;
        head = head->next;

        //释放内存
        free(node);
        node = NULL;

        //解锁
        pthread_mutex_unlock(&lock);

        sleep(2);

    }

}

void *pthread_produce(void *arg)
{
    printf("produce is star\n");
    char *name = (char *)arg;
    printf("produce name is [%s]\n",name);

    NODE *node = NULL;
    while(1)
    {
        sleep(2);
        //生产一个节点
        node = (NODE *)malloc(sizeof(NODE));
        if(node == NULL)
        {
            perror("malloc is error\n");
            exit(EXIT_FAILURE);
        }
        node->data = rand()%3;
        node->next = NULL;
        printf("produce:[%d]\n",node->data);

        //枷锁
        pthread_mutex_lock(&lock);

        //赋值
        if(NULL == head){
            head = node;
        }else{
            NODE *temp = head;
            while(temp != NULL){
                temp = temp->next;
            }
            temp = node;
        }
        //解锁
        pthread_mutex_unlock(&lock);
        //通知阻塞线程
        pthread_cond_signal(&cond);


    }

}





